/**
 * Wihidum - Efficient Broker Hierarchy for Publish Subscribe Middleware
 *
 * License      :   Apache License 2.0
 * Home Page    :   http://code.google.com/p/wihidum/
 * Mailing List :   wihidum@googlegroups.com
 */

package lk.mrt.cse.wihidum.listener.receiver;

import lk.mrt.cse.wihidum.listener.processor.*;
import org.apache.axiom.om.*;
import org.apache.axiom.soap.*;
import org.apache.axis2.*;
import org.apache.axis2.context.*;
import org.apache.axis2.receivers.*;
import org.apache.log4j.*;
import org.apache.axis2.client.*; 
import javax.xml.namespace.*;

/**
 * Entry point of the messages received to the service
 */
public class MessageReceiver
        extends AbstractInOutMessageReceiver
{

    private static final Logger logger = Logger.getLogger (MessageReceiver.class);
   
    private Processor getPublicationsProcessor;
    private SinkSubscriptionProcessor sinkSubscriptionProcessor;

    /**
     * Default contructor
     */
    public MessageReceiver ()
    {
        getPublicationsProcessor = new GetPublicationsProcessor ();        
    }

    /**
     * Process the messages
     *
     * @param inMessage  Incoming message context
     * //@param outMessage Outgoing message context
     * @throws AxisFault Exception
     */
    public void invokeBusinessLogic (MessageContext inMessage, MessageContext outMessage)
            throws AxisFault
    {
        logger.info ("Listener service received a new message");

        try
        {
            Options opts=inMessage.getOptions();
            String soapAction=opts.getAction();
            // Get hold of the request SOAP Envelope
            SOAPEnvelope requestEnvelop = inMessage.getEnvelope ();

            
            // Get the header element of request SOAP envelop
            //SOAPHeader requestEnvelopHeader = requestEnvelop.getHeader ();

            //Get the Action element which is the first element inside the header in all cases
           // OMElement actionElement = requestEnvelopHeader.getFirstChildWithName(new QName("http://www.w3.org/2005/08/addressing", "Action"));

            //Get the action in order to delegate the processing of the request accordingly
            //String action = actionElement.getText ();

            // The response element
            OMElement responseElement;


            if (soapAction.equals ("getPublications"))
            {
                logger.info ("Received message is a get publications request");

                // Hand over the message to the get publications processor
                responseElement = getPublicationsProcessor.processMessage (requestEnvelop);

                // Set the response envelope in the response message context
                outMessage.setEnvelope (createResponse (responseElement));
            }
            else if(soapAction.equals("unsubscribe"))
            {
                logger.info("Received message is a unsubscription request");
                sinkSubscriptionProcessor=new SinkSubscriptionProcessor();
                responseElement=sinkSubscriptionProcessor.processUnsubscriptionRequest(requestEnvelop);
                outMessage.setEnvelope(createResponse(responseElement));
            }
            else
            {
                logger.info ("Received message is in unrecognized format");
            }
        }
        catch (NullPointerException ex)
        {
            logger.error ("Error in recognizing received message format", ex);
        }
        catch (OMException ex)
        {
            logger.error ("Error in recognizing received message format", ex);
        }
       catch (AxisFault ex)
        {
            logger.error ("Error in recognizing received message format", ex);
        }
    }

    /**
     * Create response SOAP envelop
     *
     * @param element Response element
     * @return Created response envelop
     */
    private SOAPEnvelope createResponse (OMElement element)
    {
        // Create the response SOAP facotry
        SOAPFactory factory = OMAbstractFactory.getSOAP11Factory ();

        // Create the response SOAP envelop
        SOAPEnvelope responseEnvelop = factory.getDefaultEnvelope ();

        // Add the response to the response SOAP envelop
        responseEnvelop.getBody ().addChild (element);

        return responseEnvelop;
    }

    /**
     * Get publications processor setter method
     *
     * @param getPublicationsProcessor PublicationProcessor
     */
    public void setGetPublicationsProcessor (Processor getPublicationsProcessor)
    {
        this.getPublicationsProcessor = getPublicationsProcessor;
    }  
}
